﻿using System.Collections.Generic;
using System.Linq;
using Coder.Workflow;
using Fee.Orders.AuthProjectWorkflow;
using Fee.Orders.DesignWorkflow;
using Identity;
using JwtWebApi.Data;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace JwtWebApi.Controllers
{
    [Authorize]
    [ApiController]
    [Route("[controller]")]
    [EnableCors]
    public class UsersController : Controller
    {
        private readonly ApplicationDbContext _context;
        private readonly UserManager<User> _userManager;

        public UsersController(ApplicationDbContext context, UserManager<User> userManager)
        {
            _context = context;
            _userManager = userManager;
        }

        [HttpGet("workActivity/{workActivityId:int}/next")]
        public IActionResult ListByWorkActivity(int workActivityId)
        {
            var workActivity = _context.WorkActivities
                .Include(f => f.WorkTask)
                .Include(f => f.ProcessInstance)
                .ThenInclude(f => f.WorkProcess).ThenInclude(f => f.Items).ThenInclude(f => f.Role)
                .FirstOrDefault(f => f.Id == workActivityId);

            var workTask = workActivity.WorkTask;
            var workProcess = workActivity.ProcessInstance.WorkProcess;

            var hasNext = workProcess.TryGetNext(workActivity.WorkTask.Id, out var workTasks);

            if (!hasNext)
            {
                return Json(new
                {
                    hasNext = false,
                    successed = true,
                });
            }

            hasNext = false;
            var nextWorkTask = workTasks.First();
            IList<User> users = new List<User>();
            if (workProcess.WorkflowType == typeof(BudgetOrderWorkProcess).Name &&
                nextWorkTask.Name == BudgetOrder.DesignPlanCostStep2)
            {
                var district = _context.Set<BudgetOrder>().Where(f => f.Id == workActivity.ProcessInstance.Id)
                    .Select(f => f.ConstructionTask.Station.District).First();
                hasNext = true;
                users = (from userRole in _context.UserRoles
                         join user in _context.Users on userRole.UserId equals user.Id
                         where userRole.RoleId.Equals(nextWorkTask.Role.Id) &&
                               (user.District == null || user.District == district)
                         select user).ToList();
            }
            else if (workProcess.WorkflowType == typeof(AuthProjectOrder).Name &&
                    nextWorkTask.Name == AuthProjectOrder.ProjectAuth)
            {
                hasNext = true;
                var roleName = nextWorkTask.Role.Name;
                users = _userManager.GetUsersInRoleAsync(roleName).Result;
            }

            return Ok(new
            {
                users,
                hasNext,
                successed = true
            });
        }

        [HttpGet("workTask/{workTaskId:int}/next")]
        public IActionResult ListByWorkTask(int workTaskId)
        {
            var workTask = _context.Set<WorkTask>().FirstOrDefault(f => f.Id == workTaskId);
            var workProcess = _context.Set<WorkProcess>()
                .Include(f => f.Items).FirstOrDefault(f => f.Items.Contains(workTask));


            var hasNext = workProcess.TryGetNext(workTaskId, out var workTasks);
            if (!hasNext)
                return Ok(new
                {
                    successed = false,
                    hasNext
                });
            var nextWorkTask = workTasks.First();

            if (nextWorkTask.Role == null) _context.Entry(nextWorkTask).Reference(_ => _.Role).Load();
            IList<User> users;

            var roleName = nextWorkTask.Role.Name;
            users = _userManager.GetUsersInRoleAsync(roleName).Result;


            return Ok(new
            {
                users,
                hasNext,
                successed = true
            });
        }
    }
}